﻿using System.Collections.Generic;
using DataGeneration.Domain.DataAccessLayer;

namespace DataGeneration.Domain.CustomProcessors
{
    /// <summary>
    /// Defines the type StringProcessor
    /// </summary>
    public class StringProcessor
    {
        private static Dictionary<string, string> _alphabets;
        /// <summary>
        /// Gets the alphabets.
        /// </summary>
        /// <value>The alphabets.</value>
        public static Dictionary<string, string> Alphabets
        {
            get
            {
                return _alphabets ?? (_alphabets = new Dictionary<string, string>
                                                       {
                                                           {"1", "a"},
                                                           {"2", "b"},
                                                           {"3", "c"},
                                                           {"4", "d"},
                                                           {"5", "e"},
                                                           {"6", "f"},
                                                           {"7", "g"},
                                                           {"8", "h"},
                                                           {"9", "i"},
                                                           {"10", "j"},
                                                           {"11", "k"},
                                                           {"12", "l"},
                                                           {"13", "m"},
                                                           {"14", "n"},
                                                           {"15", "o"},
                                                           {"16", "p"},
                                                           {"17", "q"},
                                                           {"18", "r"},
                                                           {"19", "s"},
                                                           {"20", "t"},
                                                           {"21", "u"},
                                                           {"22", "v"},
                                                           {"23", "w"},
                                                           {"24", "x"},
                                                           {"25", "y"},
                                                           {"26", "z"}
                                                       });
            }
        }

        /// <summary>
        /// Generates the value.
        /// </summary>
        /// <param name="maxCharacters">The max characters.</param>
        /// <param name="upperCase">if set to <c>true</c> [upper case].</param>
        /// <returns></returns>
        public static string GenerateValue(int maxCharacters, bool upperCase)
        {
            if (upperCase)
            {
                return RandomMizer.RandomUpperCaseString(maxCharacters);
            }
            return RandomMizer.RandomString(maxCharacters);
        }

        /// <summary>
        /// Generates the unique value.
        /// </summary>
        /// <param name="maxCharacters">The max characters.</param>
        /// <param name="entityKeyFilename">The entity key filename.</param>
        /// <param name="tableName">Name of the table.</param>
        /// <param name="columnName">Name of the column.</param>
        /// <param name="upperCase">if set to <c>true</c> [upper case].</param>
        /// <param name="dataAccess">The data access.</param>
        /// <returns></returns>
        public static string GenerateUniqueValue(int maxCharacters, string entityKeyFilename, string tableName, string columnName, bool upperCase, DataAccess dataAccess)
        {
            int loopCounter = 0;
            string testValue = RandomMizer.RandomString(maxCharacters);

            while (DatabaseHelper.IsValueInDatabase(tableName, columnName, testValue, dataAccess))
            {
                testValue = RandomMizer.RandomString(maxCharacters);

                loopCounter++;
                if (loopCounter == int.MaxValue)
                {
                    //we have already tried all possible combinations and it will still violate the unique constraint!
                    //so lets bail out and db will raise error! The user must reconsider dataload xml.
                    break;
                }
            }

            if (upperCase)
            {
                return testValue.ToUpper();
            }

            return testValue;
        }

        public static string GenerateUniqueUsername(int maxCharacters, string entityKeyFilename, string tableName, string columnName, bool upperCase, DataAccess dataAccess)
        {
            int loopCounter = 0;
            string testValue = GenerateUsername(maxCharacters);

            while (DatabaseHelper.IsValueInDatabase(tableName, columnName, testValue, dataAccess))
            {
                testValue = GenerateUsername(maxCharacters);
                loopCounter++;
                if (loopCounter == int.MaxValue)
                {
                    //we have already tried all possible combinations and it will still violate the unique constraint!
                    //so lets bail out and db will raise error! The user must reconsider dataload xml.
                    break;
                }
            }

            if (upperCase)
            {
                return testValue.ToUpper();
            }

            return testValue;
        }

        public static string GeneratePatternedUsername(string patternString, string entityKeyFilename, string tableName, string columnName, DataAccess dataAccess, int currentIteration,int startValue)
        {
            int loopCounter = currentIteration;
            string testValue = string.Format("{0}{1}", patternString, currentIteration + startValue);

            while (DatabaseHelper.IsValueInDatabase(tableName, columnName, testValue, dataAccess))
            {
                testValue = string.Format("{0}{1}", patternString, ++currentIteration + startValue);
                loopCounter++;
                if (loopCounter == int.MaxValue)
                {
                    //we have already tried all possible combinations and it will still violate the unique constraint!
                    //so lets bail out and db will raise error! The user must reconsider dataload xml.
                    break;
                }
            }

            return testValue;
        }
        
        public static string GeneratePatternedPassword(string patternString, int currentIteration, int startValue)
        {
            return string.Format("{0}{1}", patternString, currentIteration + startValue);
        }

        private static string GenerateUsername(int maxCharacters)
        {
            string testValue;
            if (maxCharacters >= 10)
            {
                testValue = string.Format("{0}{1:000}", HumanNameGenerator.HumanName,
                                          RandomMizer.GetNextValue(0, 999));
            }
            else
            {
                testValue = RandomMizer.RandomString(maxCharacters);
            }
            return testValue;
        }
    }
}
